/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package umlapp.elements;

import java.awt.Color;
import java.awt.Graphics;
import umlapp.Drawable;
import umlapp.diagrams.Relationships;
import umlapp.icons.ImageLoader;

/**
 *
 * Trieda reprezentujúca vzťah typu generalizácia.
 *
 * @author Peter Chovanec
 * @author Mario Jaros
 */
public class GeneralizationElement extends AElement implements Relationships {

    /**
     * Drawable objekty, medzi ktorými existuje tento vzťah.
     */
    private Drawable startDrawable, endDrawable;

    /**
     * Konštruktor triedy priraduje inštancie atributom
     *
     * @param name
     * @param dimension
     * @param startDrawable
     * @param endDrawable
     */
    public GeneralizationElement(String name, Dimension dimension, Drawable startDrawable,
            Drawable endDrawable) {
        super(name, dimension);
        this.startDrawable = startDrawable;
        this.endDrawable = endDrawable;
    }

    /**
     * Metoda na vykreslenie elementu, blizsie je okomentovana vo vnutri
     *
     * @param g
     */
    @Override
    public void drawElement(Graphics g) {
        // Pomocne premenne na kontrolu polohy koncoveho elementu voci zaciatocnemu.
        boolean leftUp = (isOnTheLeft() && isUp());
        boolean leftMiddle = (isOnTheLeft() && !(isUp()) && !(isDown()));
        boolean leftDown = (isOnTheLeft() && isDown());
        boolean middleUp = (isUp() && !(isOnTheLeft()) && !(isOnTheRight()));
        boolean middleDown = (isDown() && !(isOnTheLeft()) && !(isOnTheRight()));
        boolean rightUp = (isOnTheRight() && isUp());
        boolean rightMiddle = (isOnTheRight() && !(isUp()) && !(isDown()));
        boolean rightDown = (isOnTheRight() && isDown());
        int x1 = 0, y1 = 0, x2 = 0, y2 = 0;

        // Nastavenie farby.
        Color c = new Color(128, 128, 255);
        g.setColor(c);


        // Konkretne vykreslovanie asociacii, vykresluje sa podla vzajomnej polohy medzi elementami.
        // Zaciatok ma vzdy na strede hrany.
        if (leftUp) {
            x1 = startDrawable.getDimension().x;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height / 2;
            x2 = endDrawable.getDimension().x + endDrawable.getDimension().width / 2;
            y2 = endDrawable.getDimension().y + endDrawable.getDimension().height;
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x2, y1, x2, y2);
            g.drawImage(ImageLoader.generalizationUp, x2 - 9, y2 + 1, null);

        }

        if (leftMiddle) {
            x1 = startDrawable.getDimension().x;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height / 2;
            x2 = endDrawable.getDimension().x + endDrawable.getDimension().width;
            y2 = endDrawable.getDimension().y + endDrawable.getDimension().height / 2;
            if ((y1 < endDrawable.getDimension().y)) {
                y1 = y1 + (endDrawable.getDimension().y - y1);
            }
            if ((y1 > (endDrawable.getDimension().y + endDrawable.getDimension().height))) {
                y1 = y1 - (y1 - (endDrawable.getDimension().y + endDrawable.getDimension().height));
            }
            g.drawLine(x1, y1, x2, y1);
            g.drawImage(ImageLoader.generalizationLeft, x2 + 1, y1 - 9, null);
        }

        if (leftDown) {
            x1 = startDrawable.getDimension().x;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height / 2;
            x2 = endDrawable.getDimension().x + endDrawable.getDimension().width / 2;
            y2 = endDrawable.getDimension().y;
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x2, y1, x2, y2);
            g.drawImage(ImageLoader.generalizationDown, x2 - 9, y2 - 14, null);
        }

        if (middleUp) {
            x1 = startDrawable.getDimension().x + startDrawable.getDimension().width / 2;
            y1 = startDrawable.getDimension().y;
            x2 = endDrawable.getDimension().x + endDrawable.getDimension().width / 2;
            y2 = endDrawable.getDimension().y + endDrawable.getDimension().height;
            if ((x1 < endDrawable.getDimension().x)) {
                x1 = x1 + (endDrawable.getDimension().x - x1);
            }
            if ((x1 > (endDrawable.getDimension().x + endDrawable.getDimension().width))) {
                x1 = x1 - (x1 - (endDrawable.getDimension().x + endDrawable.getDimension().width));
            }
            g.drawLine(x1, y1, x1, y2);
            g.drawImage(ImageLoader.generalizationUp, x1 - 9, y2 + 1, null);
        }

        if (middleDown) {
            x1 = startDrawable.getDimension().x + startDrawable.getDimension().width / 2;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height;
            x2 = endDrawable.getDimension().x + startDrawable.getDimension().width / 2;
            y2 = endDrawable.getDimension().y;
            if ((x1 < endDrawable.getDimension().x)) {
                x1 = x1 + (endDrawable.getDimension().x - x1);
            }
            if ((x1 > (endDrawable.getDimension().x + endDrawable.getDimension().width))) {
                x1 = x1 - (x1 - (endDrawable.getDimension().x + endDrawable.getDimension().width));
            }
            g.drawLine(x1, y1, x1, y2);
            g.drawImage(ImageLoader.generalizationDown, x1 - 9, y2 - 14, null);
        }

        if (rightUp) {
            x1 = startDrawable.getDimension().x + startDrawable.getDimension().width;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height / 2;
            x2 = endDrawable.getDimension().x + endDrawable.getDimension().width / 2;
            y2 = endDrawable.getDimension().y + endDrawable.getDimension().height;
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x2, y1, x2, y2);
            g.drawImage(ImageLoader.generalizationUp, x2 - 9, y2 + 1, null);
        }

        if (rightMiddle) {
            x1 = startDrawable.getDimension().x + startDrawable.getDimension().width;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height / 2;
            x2 = endDrawable.getDimension().x;
            y2 = endDrawable.getDimension().y + endDrawable.getDimension().height / 2;
            if ((y1 < (endDrawable.getDimension().y))) {
                y1 = y1 + (endDrawable.getDimension().y - y1);
            }
            if ((y1 > (endDrawable.getDimension().y + endDrawable.getDimension().height))) {
                y1 = y1 - (y1 - (endDrawable.getDimension().y + endDrawable.getDimension().height));
            }
            g.drawLine(x1, y1, x2, y1);
            g.drawImage(ImageLoader.generalizationRight, x2 - 14, y1 - 9, null);
        }

        if (rightDown) {
            x1 = startDrawable.getDimension().x + startDrawable.getDimension().width;
            y1 = startDrawable.getDimension().y + startDrawable.getDimension().height / 2;
            x2 = endDrawable.getDimension().x + endDrawable.getDimension().width / 2;
            y2 = endDrawable.getDimension().y;
            g.drawLine(x1, y1, x2, y1);
            g.drawLine(x2, y1, x2, y2);
            g.drawImage(ImageLoader.generalizationDown, x2 - 9, y2 - 14, null);
        }
    }

    /**
     * Pomocne metody na urcovanie polohy medzi elementami, porovnavaju sa suradnice jednotlivych
     * elementov.
     */
    public boolean isOnTheLeft() {
        int startX = startDrawable.getDimension().x;
        int endX = endDrawable.getDimension().x + endDrawable.getDimension().width;
        if (endX < startX) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Pomocne metody na urcovanie polohy medzi elementami, porovnavaju sa suradnice jednotlivych
     * elementov.
     */
    public boolean isOnTheRight() {
        int startX = startDrawable.getDimension().x + startDrawable.getDimension().width;
        int endX = endDrawable.getDimension().x;
        if (endX > startX) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Pomocne metody na urcovanie polohy medzi elementami, porovnavaju sa suradnice jednotlivych
     * elementov.
     */
    public boolean isUp() {
        int startY = startDrawable.getDimension().y;
        int endY = endDrawable.getDimension().y + endDrawable.getDimension().height;
        if (endY < startY) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Pomocne metody na urcovanie polohy medzi elementami, porovnavaju sa suradnice jednotlivych
     * elementov.
     */
    public boolean isDown() {
        int startY = startDrawable.getDimension().y + endDrawable.getDimension().height;
        int endY = endDrawable.getDimension().y;
        if (endY > startY) {
            return true;
        } else {
            return false;
        }
    }
    /*
     * implementovana trieda z rohrania Drawable
     */

    @Override
    public AElement getStartDrawable() {
        return (AElement) startDrawable;
    }
    /*
     * implementovana trieda z rohrania Drawable
     */

    @Override
    public AElement getEndDrawable() {
        return (AElement) endDrawable;
    }
}
